<!DOCTYPE html>
<html>
	<head>
		<meta charset=utf-8>
		<title>My first Three.js app</title>
		<style>
			body {
				margin: 0;
				overflow: hidden;
			}
			canvas {
        width: 100%;
        height: 100%
      }
		</style>
		<script src="js/three.js"></script>
		<script src="js/FirstPersonControls.js"></script>
		<script src="js/algorithm.js"></script>
		<script src="js/columns_model.js"></script>
		<script src="js/data_structure.js"></script>
	</head>
	<body>

	<script>
		/* 声明变量 */
		// THREE
		var controls;
		var scene;
		var camera;
		var renderer;
		var light;
		var clock;

		// Model、 Algorithm
		var columnsModel1, columnsModel2, columnsModel3, columnsModel4;
		var quickSortGenerator1, quickSortGenerator2, quickSortGenerator3, quickSortGenerator4;


		/* 定义函数 */
		function init_columns(numColumns, begin, orientation) {
			var columnsModel = ColumnsModel(begin, orientation);
			for(var i = 0; i < numColumns; i++) {
				columnsModel.create_column(Math.floor(Math.random() * (100)) + 1);
			}
			return columnsModel;
		}

		function add_all_to(scene, columns) {
			columns.forEach(function(element) {
				scene.add(element);
			});
		}

		function render() {
			requestAnimationFrame( render );
			renderer.render( scene, camera );
			quickSortGenerator1.next();
			quickSortGenerator2.next();
			quickSortGenerator3.next();
			quickSortGenerator4.next();

			columnsModel1.justify_position();
			columnsModel2.justify_position();
			columnsModel3.justify_position();
			columnsModel4.justify_position();

			controls.update( clock.getDelta());
		}

		function on_key_press(evt) {
			evt = evt || window.event;
			var charCode = evt.keyCode || evt.which;

			// todo: check escape key
			if( charCode === 27) {  //escape
				controls.enabled = false;
			}

			var charStr = String.fromCharCode(charCode);
			switch(charStr) {
				case 'v':
					//todo: if the browser support
					var element = document.body;
					element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
					element.requestPointerLock();
					controls.enabled = true;
					break;
			}
		}

		// Caller Scope Implemented Algorithm High Order function
		function smaller_than(cube1, cube2) {
			return cube1.geometry.parameters.height < cube2.geometry.parameters.height;
		}

		function larger_than(cube1, cube2) {
			return cube1.geometry.parameters.height > cube2.geometry.parameters.height;
		}

		function swap(array, a, b) {
			var temp = array[a];
			array[a] = array[b];
			array[b] = temp;
		}

		function move_to(fromEle, array, toIndex) {
			array[toIndex] = fromEle;
		}


		/* Start  开始 */
		// THREE
		camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );

		renderer = new THREE.WebGLRenderer();
		renderer.setSize( window.innerWidth, window.innerHeight );

		light = new THREE.PointLight( 0xffffff, 100, 0 );
		light.position.set(0, 200, 0 );

		scene = new THREE.Scene();
		scene.add( light );

		controls = new THREE.FirstPersonControls( camera );
		controls.movementSpeed = 200;
		controls.lookSpeed = 30;
		controls.noFly = true;
		controls.lookVertical = true;
		controls.enabled = false;

		document.body.appendChild( renderer.domElement );


		// models
		columnsModel1 = init_columns(250, [-250, -300], [2, 0]);
		columnsModel2 = init_columns(250, [-250, -300], [0, 2]);
		columnsModel3 = init_columns(250, [-250, 200], [2, 0]);
		columnsModel4 = init_columns(250, [250, 200], [0, -2]);
		add_all_to(scene, columnsModel1.columns);
		add_all_to(scene, columnsModel2.columns);
		add_all_to(scene, columnsModel3.columns);
		add_all_to(scene, columnsModel4.columns);


		// algorithm runner
		quickSortGenerator1 = Algorithm.quick_sort(columnsModel1.columns, 0, columnsModel1.columns.length-1, swap, smaller_than);
		quickSortGenerator2 = Algorithm.quick_sort(columnsModel2.columns, 0, columnsModel2.columns.length-1, swap, larger_than);
		quickSortGenerator3 = Algorithm.quick_sort(columnsModel3.columns, 0, columnsModel3.columns.length-1, swap, smaller_than);
		quickSortGenerator4 = Algorithm.quick_sort(columnsModel4.columns, 0, columnsModel4.columns.length-1, swap, larger_than);


		// Start rendering
		clock = new THREE.Clock();
		render();

		// key, user interaction
		document.onkeypress = on_key_press;





/* For Mobile */
//		var gamma = 0;
//		var beta = 0;
//		var i = 0;
//		window.addEventListener('devicemotion', function(event) {
////			console.log(event.acceleration.x + ' m/s2');
////			var z = event.rotationRate.alpha;
////			var x = event.rotationRate.beta;
////			var y = event.rotationRate.gamma;
//			if(i % 50 === 0) {
//				console.log(event.rotationRate.alpha, beta, gamma);
//				gamma += event.rotationRate.gamma;
//				beta += event.rotationRate.beta;
//				var x = Math.cos(gamma);
//				var y = Math.sin(beta);
//				var z = -Math.sin(gamma) - Math.cos(beta);
//				console.log(x, y, z);
//				camera.lookAt( new THREE.Vector3( x, y, z ) )
//			}
//			i++;
//		});

    // Ask the browser to lock the pointer
	</script>
	</body>
</html>
